package com.ruoyi.system.service.impl;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;

import start.spring.basic.util.common.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.GgPzRedisMapper;
import com.ruoyi.system.domain.GgPzRedis;
import com.ruoyi.system.service.IGgPzRedisService;

import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.JedisPoolConfig;

import com.ruoyi.system.service.BaseServiceImpl;

import start.spring.basic.page.PageQuery;
import start.spring.basic.page.PageResult;
import start.spring.basic.response.ResponseData;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

/**
 * redis配置Service业务层处理
 * 
 * @author xuyy
 * @date 2023-08-07
 */
@Slf4j
@Service
public class GgPzRedisServiceImpl extends BaseServiceImpl implements IGgPzRedisService {
    
    @Autowired
    private GgPzRedisMapper ggPzRedisMapper;

    /**
     * 查询redis配置列表
     * 
     * @param ggPzRedis redis配置
     * @return redis配置
     */
    @Override
    public PageResult<GgPzRedis> selectGgPzRedisPageList(PageQuery pageQuery,GgPzRedis ggPzRedis) {
        IPage<GgPzRedis> page = super.getPage(pageQuery);
        QueryWrapper<GgPzRedis> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(!StringUtil.isEmpty(ggPzRedis.getRedisId()), GgPzRedis::getRedisId, ggPzRedis.getRedisId());
    	queryWrapper.lambda().eq(!StringUtil.isEmpty(ggPzRedis.getIp()), GgPzRedis::getIp, ggPzRedis.getIp());
        queryWrapper.lambda().like(!StringUtil.isEmpty(ggPzRedis.getBz()), GgPzRedis::getBz, ggPzRedis.getBz());
        page = this.ggPzRedisMapper.selectPage(page, queryWrapper);
        return super.getPageResult(page);
    }
    
    /**
     * 查询全量redis配置
     * 
     * @param ggPzRedis redis配置
     * @return redis配置
     */
    @Override
    public List<GgPzRedis> selectGgPzRedisList(GgPzRedis ggPzRedis) {
        QueryWrapper<GgPzRedis> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(!StringUtil.isEmpty(ggPzRedis.getRedisId()), GgPzRedis::getRedisId, ggPzRedis.getRedisId());
    	queryWrapper.lambda().eq(!StringUtil.isEmpty(ggPzRedis.getIp()), GgPzRedis::getIp, ggPzRedis.getIp());
        queryWrapper.lambda().like(!StringUtil.isEmpty(ggPzRedis.getBz()), GgPzRedis::getBz, ggPzRedis.getBz());
        return this.ggPzRedisMapper.selectList(queryWrapper);
    }

    /**
     * 新增redis配置
     * 
     * @param ggPzRedis redis配置
     * @return 结果
     */
    @Override
    public int insertGgPzRedis(GgPzRedis ggPzRedis) {
        return this.ggPzRedisMapper.insert(ggPzRedis);
    }

    /**
     * 修改redis配置
     * 
     * @param ggPzRedis redis配置
     * @return 结果
     */
    @Override
    public int updateGgPzRedis(GgPzRedis ggPzRedis) {
    	UpdateWrapper<GgPzRedis> updateWrapper = new UpdateWrapper<>();
    	updateWrapper.lambda().eq(GgPzRedis::getRedisId, ggPzRedis.getRedisId());
        return this.ggPzRedisMapper.update(ggPzRedis, updateWrapper);
    }

	@Override
	public ResponseData<String> testGgPzRedisByRedisIds(List<String> redisIds) {
		String redisId = redisIds.get(0);
		QueryWrapper<GgPzRedis> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(!StringUtil.isEmpty(redisId), GgPzRedis::getRedisId, redisId);
        GgPzRedis ggPzRedis = this.ggPzRedisMapper.selectOne(queryWrapper);
        if(ggPzRedis!=null) {
        	return testRedisConfig(ggPzRedis);
        }else {
        	return ResponseData.errorMsg("未查询到redis配置信息，请传入正确的redis唯一标志！");
        }
	}
	
	private ResponseData<String> testRedisConfig(GgPzRedis ggPzRedis) {
		JedisConnectionFactory jedisConnectionFactory = null;
    	try {
    		JedisPoolConfig poolConfig=new JedisPoolConfig();
			poolConfig.setMaxTotal(ggPzRedis.getMaxTotal());
			poolConfig.setMaxWaitMillis(ggPzRedis.getMaxWaitMillis());
			poolConfig.setMaxIdle(ggPzRedis.getMaxIdle());
			poolConfig.setTestOnBorrow(false);
			poolConfig.setTestWhileIdle(true);
			poolConfig.setTimeBetweenEvictionRunsMillis(30000);
			poolConfig.setMinEvictableIdleTimeMillis(600000);
			
	        //获得默认的连接池构造器(怎么设计的，为什么不抽象出单独类，供用户使用呢) 有毒
	        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
	                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder()
	                .connectTimeout(Duration.ofSeconds(ggPzRedis.getTimeout()))
	                .readTimeout(Duration.ofSeconds(ggPzRedis.getTimeout()));
	        //指定jedisPoolConifig来修改默认的连接池构造器（真麻烦，滥用设计模式！） ！！！！
	        jpcb.poolConfig(poolConfig);
	        //通过构造器来构造jedis客户端配置
	        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
			
			RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
			redisStandaloneConfiguration.setHostName(ggPzRedis.getIp().trim());
			redisStandaloneConfiguration.setPort(Integer.parseInt(String.valueOf(ggPzRedis.getPort()).trim()));
			if(!StringUtil.isEmpty(ggPzRedis.getPwd())){
				redisStandaloneConfiguration.setPassword(ggPzRedis.getPwd().trim());
			}
			
			jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration,jedisClientConfiguration);
			
			jedisConnectionFactory.afterPropertiesSet();
			StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(jedisConnectionFactory);
			stringRedisTemplate.opsForValue().set("a", "1", 1, TimeUnit.SECONDS);
			
			return ResponseData.successMsg("测试通过！");
    	}catch(Exception e) {
    		log.error("测试redis配置信息报错！", e);
    		return ResponseData.errorMsg("测试失败，请检查配置是否正确，网络是否联通！");
    	}finally {
			if(jedisConnectionFactory!=null) {
				jedisConnectionFactory.destroy();
			}
		}
	}
	
}
